package com.ruoyi.util;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import okhttp3.*;
import okhttp3.internal.sse.RealEventSource;
import okhttp3.sse.EventSourceListener;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;
import java.util.concurrent.TimeUnit;

@Component
public class OkHttpUtils {

    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

    private final OkHttpClient.Builder clientBuilder;

    private final OkHttpClient client;

    private LoadingCache<String, OkHttpClient> proxyClients;

    public OkHttpUtils() {
        clientBuilder = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                // 设置读超时
                .readTimeout(300, TimeUnit.SECONDS)
                // 设置写超时
                .writeTimeout(10, TimeUnit.SECONDS)
                // 是否自动重连
                .retryOnConnectionFailure(true);
        client = clientBuilder.build();

        CacheLoader<String, OkHttpClient> loader = new CacheLoader<String, OkHttpClient>() {

            @Override
            public OkHttpClient load(String key) {
                String[] s = key.split(":", 2);
                if (s.length < 2) {
                    return client;
                }
                Proxy p = new Proxy(Type.HTTP, new InetSocketAddress(s[0], Integer.parseInt(s[1])));
                return clientBuilder.proxy(p).build();
            }
        };
        proxyClients = CacheBuilder.newBuilder().maximumSize(100).build(loader);
    }

//    public String doPostJson(String url, String paramsJson) throws IOException {
//        RequestBody body = RequestBody.create(paramsJson, JSON);
//        Request request = new Request.Builder().url(url).post(body).build();
//        try (Response response = client.newCall(request).execute()) {
//            if (response.body() != null) {
//                return response.body().string();
//            }
//        }
//        return null;
//    }

    public String doPostJson(String url, String paramsJson, Headers header) throws IOException {
        return doPostJson(url, paramsJson, header, null);
    }
    public String doPostJson(String url, String paramsJson, Headers header, String proxy) throws IOException {
        RequestBody body = RequestBody.create(paramsJson, JSON);
        Request request = new Request.Builder().url(url).headers(header).post(body).build();
        try (Response response = getClient(proxy).newCall(request).execute()) {
            if (response.body() != null) {
                return response.body().string();
            }
        }
        return null;
    }

    private OkHttpClient getClient(String host) {
        if (StringUtils.isEmpty(host)) {
            return client;
        }
        return proxyClients.getUnchecked(host);
    }

    public void doPostJsonStream(String url, String paramsJson, Headers header, final EventSourceListener listener) {
        doPostJsonStream(url, paramsJson, header, listener, null);
    }
    public void doPostJsonStream(String url, String paramsJson, Headers header, final EventSourceListener listener, String proxy) {
        RequestBody body = RequestBody.create(paramsJson, JSON);
        Request request = new Request.Builder().url(url).headers(header).post(body).build();
        // 实例化EventSource，注册EventSource监听器
        final RealEventSource realEventSource = new RealEventSource(request, listener);
        realEventSource.connect(getClient(proxy));
    }

}